<template>
	<div class="DisArticle-header" :class="{ 'fixed-header': isScrolled }">
		<Header />
	</div>
	<div class="DisArticle-body">
		<div class="DisArticle-box">
			<Text v-if="article"/>
			<div class="outline-container">
				<div class="outline-title">
					<i class="outline-icon"></i>
					<span>文章大纲</span>
				</div>
				<div class="outline-content" v-if="headings.length > 0">
					<div 
						v-for="(heading, index) in headings" 
						:key="index" 
						class="outline-item"
						:class="{ 'level-1': heading.level === 1, 'level-2': heading.level === 2, 'level-3': heading.level === 3 }"
						@click="scrollToHeading(heading.id)"
					>
						{{ heading.text }}
					</div>
				</div>
				<div class="outline-empty" v-else>
					暂无大纲
				</div>
			</div>
		</div>
	</div>
</template>

<script setup>
	import {
		ref,
		onMounted,
		onUnmounted,
		reactive,
		computed,
		provide
	} from 'vue';
	import { useRouter } from 'vue-router';
	
	
	import {
		onClickOutside
	} from '@vueuse/core';
	import Header from '../../header/Header.vue'; // 引入你的 Header 组件
	import Text from './text/Text.vue'; // 引入 Text 组件

	const isScrolled = ref(false);
	const intervalId = ref(null);
	const lastScrollTop = ref(0);
	const articleActiveRef = ref(null);
	const isshowTimeLine = ref(false);
	const showClassTimeoutId = ref(null);

	const handleScroll = () => {
		// 获取当前窗口的垂直滚动距离 (兼容多种浏览器)
		const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
		const headerHeight = 50; // 你的头部实际高度，用于判断是否滚过了头部

		// 判断滚动方向
		if (currentScrollTop > lastScrollTop.value && currentScrollTop > headerHeight) {
			// --- 向下滚动 ---
			// 当前滚动位置 > 上次位置，表示向下滚动
			// 并且，滚动距离已经超过了头部的高度 (避免刚开始滚动一点点就隐藏)
			// 设置 isScrolled 为 true，这将给 .Index-header 添加 'fixed-header' 类
			isScrolled.value = true;

		} else if (currentScrollTop < lastScrollTop.value) {
			// --- 向上滚动 ---
			// 当前滚动位置 < 上次位置，表示向上滚动
			// 设置 isScrolled 为 false，这将移除 'fixed-header' 类
			isScrolled.value = false;
		}
		// else {
		// 如果 currentScrollTop === lastScrollTop.value (例如水平滚动或无垂直滚动)，则不改变状态
		// 如果 currentScrollTop <= headerHeight 并且向下滚动，也不隐藏，保持显示
		// }

		// 更新上一次滚动的位置，为下一次事件触发时的比较做准备
		// 使用 Math.max 确保 lastScrollTop 的值不会小于 0 (虽然 scrollTop 通常不会为负)
		lastScrollTop.value = Math.max(0, currentScrollTop);

		// 检查当前滚动位置与标题位置的关系，以便高亮显示当前标题
		highlightCurrentHeading(currentScrollTop);
	};

	// 添加用于高亮当前可见标题的函数
	const highlightCurrentHeading = (scrollPosition) => {
		if (headings.value.length === 0) return;

		// 找到当前可见的标题
		let currentIndex = -1;
		for (let i = headings.value.length - 1; i >= 0; i--) {
			const element = document.getElementById(headings.value[i].id);
			if (element && element.offsetTop <= scrollPosition + 100) {
				currentIndex = i;
				break;
			}
		}

		// 更新高亮状态
		if (currentIndex >= 0) {
			headings.value.forEach((heading, index) => {
				heading.active = index === currentIndex;
			});
		}
	};

	// 函数：解析HTML内容中的所有标题标签
	const parseHeadings = (htmlContent) => {
		const parser = new DOMParser();
		const doc = parser.parseFromString(htmlContent, 'text/html');
		
		// 查找所有h1-h6标签
		const headingElements = doc.querySelectorAll('h1, h2, h3, h4, h5, h6');
		
		// 将NodeList转换为数组并提取所需信息
		return Array.from(headingElements).map((element, index) => {
			// 获取标题级别（数字1-6）
			const level = parseInt(element.tagName.substring(1), 10);
			
			// 获取标题文本内容
			const text = element.textContent.trim();
			
			// 为每个标题生成唯一ID
			const id = `heading-${index}`;
			
			return { id, level, text, active: false };
		});
	};

	// 函数：在实际内容中添加ID以便跳转
	const addIdsToHeadings = () => {
		// 解析并添加ID到实际DOM中的标题元素
		const articleContent = document.querySelector('.article-content');
		if (articleContent) {
			const headingElements = articleContent.querySelectorAll('h1, h2, h3, h4, h5, h6');
			headingElements.forEach((element, index) => {
				element.id = `heading-${index}`;
			});
		}
	};

	// 函数：滚动到指定ID的标题位置
	const scrollToHeading = (id) => {
		const element = document.getElementById(id);
		if (element) {
			// 滚动到标题位置，顶部留出一些空间以避免被头部遮挡
			const headerOffset = 60;
			const elementPosition = element.getBoundingClientRect().top;
			const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
			
			window.scrollTo({
				top: offsetPosition,
				behavior: 'smooth'
			});
		}
	};

	// 创建计算属性以解析文章内容中的标题
	const headings = computed(() => {
		// 如果文章内容为空，返回空数组
		if (!article.value || !article.value.content) {
			return [];
		}
		
		// 解析HTML内容中的标题
		return parseHeadings(article.value.content);
	});
	
	const router = useRouter();

	onMounted(() => {
		const ar = sessionStorage.getItem("article");
		if (!ar) {
			console.log("DisArticle: sessionStorage中没有文章数据，重定向到首页");
			router.push('/');
			return;
		}
		
		article.value = JSON.parse(ar);
		console.log("DisArticle: 成功加载文章数据", article.value.title);
		
		// 向 window 对象添加 'scroll' 事件监听器，并指定 handleScroll 函数作为回调
		window.addEventListener('scroll', handleScroll);

		// 在DOM中添加ID以便跳转
		setTimeout(() => {
			addIdsToHeadings();
		}, 500);

		// 监听点击外部事件
		onClickOutside(articleActiveRef, () => {
			if (isshowTimeLine.value) {
				isshowTimeLine.value = false;
			}
		});

	});

	// 组件卸载前执行
	onUnmounted(() => {
		// 从 window 对象移除之前添加的 'scroll' 事件监听器
		// 传入相同的 handleScroll 函数引用以确保正确移除
		// 这是非常重要的，可以防止内存泄漏
		window.removeEventListener('scroll', handleScroll);
		if (intervalId.value) {
			clearInterval(intervalId.value);
		}
		// Clear any pending timeout for adding the class effect
		if (showClassTimeoutId.value) {
			clearTimeout(showClassTimeoutId.value);
		}
	});

	

	const article = ref();
	
	// 为子组件提供文章数据
	provide('article', article);
</script>

<style lang="scss">
	* {
		margin: 0px;
		padding: 0px;
		border: none;
		border-radius: 0px;
		font-size: 14px;
		font-weight: 300px;
		color: #000;
	}

	.DisArticle-header {
		width: 100%;
		height: 50px;
		position: fixed;
		top: 0;
		left: 0;
		z-index: 10;
		transition: transform 0.3s ease;
		transform: translateY(0);
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
		background-color: #fff;
	}

	.fixed-header {
		transform: translateY(-100%);
	}

	.DisArticle-body {
		width: 100%;
		min-height: 100vh;
		display: flex;
		justify-content: center;
		background-color: #f5f7f9;
		padding-bottom: 50px;

		.DisArticle-box {
			width: 85%;
			position: relative;
			display: flex;
			margin-top: 70px;
			overflow: visible;
		}
	}
	
	/* 大纲容器样式 */
	.outline-container {
		position: fixed;
		right: 5%;
		top: 100px;
		width: 240px;
		max-height: 75vh;
		background-color: #fff;
		border-radius: 10px;
		box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
		overflow-y: auto;
		transition: all 0.3s ease;
		padding: 20px;
		
		&::-webkit-scrollbar {
			width: 4px;
		}
		
		&::-webkit-scrollbar-track {
			background: #f1f1f1;
		}
		
		&::-webkit-scrollbar-thumb {
			background: #ccc;
			border-radius: 2px;
		}
		
		&::-webkit-scrollbar-thumb:hover {
			background: #999;
		}
		
		&:hover {
			box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
		}
	}
	
	.outline-title {
		font-size: 16px;
		font-weight: bold;
		margin-bottom: 18px;
		padding-bottom: 12px;
		border-bottom: 1px solid #eee;
		display: flex;
		align-items: center;
		position: relative;
		
		&::after {
			content: '';
			position: absolute;
			bottom: -1px;
			left: 0;
			width: 60px;
			height: 3px;
			background-color: var(--primary-color);
			border-radius: 1.5px;
		}
		
		.outline-icon {
			display: inline-block;
			width: 20px;
			height: 20px;
			margin-right: 10px;
			background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%233498db" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>');
			background-size: contain;
			background-repeat: no-repeat;
		}
		
		span {
			font-size: 17px;
			color: #333;
			font-weight: 600;
		}
	}
	
	.outline-content {
		display: flex;
		flex-direction: column;
		gap: 6px;
	}
	
	.outline-item {
		cursor: pointer;
		padding: 10px 12px;
		border-radius: 6px;
		transition: all 0.2s ease;
		font-size: 14px;
		color: #555;
		position: relative;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		
		&:hover {
			background-color: #f0f7ff;
			color: #3498db;
		}
		
		&.active {
			background-color: #e6f2ff;
			color: #2980b9;
			font-weight: bold;
			box-shadow: 0 2px 4px rgba(52, 152, 219, 0.1);
			
			&::before {
				content: '';
				position: absolute;
				left: 0;
				top: 0;
				width: 4px;
				height: 100%;
				background-color: #3498db;
				border-radius: 0 2px 2px 0;
			}
		}
		
		&.level-1 {
			font-weight: 600;
			color: #333;
			margin-top: 5px;
			
			&:first-child {
				margin-top: 0;
			}
		}
		
		&.level-2 {
			padding-left: 24px;
			font-size: 13px;
			
			&::before {
				content: '';
				position: absolute;
				left: 12px;
				top: 50%;
				width: 5px;
				height: 5px;
				border-radius: 50%;
				background-color: #3498db;
				transform: translateY(-50%);
				opacity: 0.7;
			}
		}
		
		&.level-3 {
			padding-left: 36px;
			font-size: 12px;
			color: #666;
			
			&::before {
				content: '';
				position: absolute;
				left: 24px;
				top: 50%;
				width: 4px;
				height: 4px;
				border-radius: 50%;
				background-color: #bbb;
				transform: translateY(-50%);
			}
		}
	}
	
	.outline-empty {
		color: #999;
		font-style: italic;
		text-align: center;
		padding: 30px 0;
		background-color: #f9f9f9;
		border-radius: 6px;
		margin-top: 10px;
	}
</style>